package com.caigou.controller;

import com.caigou.bean.cms.entity.UserBaseInfo;
import com.caigou.bean.cms.param.UserRealNameParam;
import com.caigou.bean.cms.param.UsersParam;
import com.caigou.bean.cms.param.UsersUpdateParam;
import com.caigou.bean.exam.entity.UserInfo;
import com.caigou.bean.exam.entity.Users;
import com.caigou.bean.exam.param.EditUserInfoParam;
import com.caigou.bean.exam.param.MsgCodeParam;
import com.caigou.bean.exam.param.RegisterUserParam;
import com.caigou.bean.exam.param.UserRegisterParam;
import com.caigou.bean.exam.vo.CurrentUserVO;
import com.caigou.bean.exam.vo.MsgCodeVO;
import com.caigou.bean.exam.vo.UserVO;
import com.caigou.bean.vo.UserRegisterVO;
import com.caigou.enums.FailResultEnum;
import com.caigou.enums.ResponseEnum;
import com.caigou.security.utils.CurrentUser;
import com.caigou.service.IUsersService;
import com.caigou.util.Result;
import com.caigou.util.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

@Slf4j
@Api(tags = "用户", description = "查询当前用户权限、用户注册、忘记密码、用户发送短信")
@RestController
@RequestMapping("/user")
public class UserInfoController {


    @Resource
    private IUsersService usersService;


    
    /**
     * 查询用户是否填写真实姓名
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "查询用户是否填写真实姓名", notes = "查询用户是否填写真实姓名")
    @GetMapping("/real/name")
    public Result<String> findUsersRealNameByParam(@RequestBody UserRealNameParam param) {
        return usersService.findUsersRealNameByParam(param);
    }


    /**
     * 添加用户真实姓名接口
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "添加用户真实姓名接口", notes = "添加用户真实姓名接口")
    @PostMapping("/real/name/add")
    public Result<String> addUsersRealName(@RequestBody UserRealNameParam param) {
        return usersService.addUsersRealName(param);
    }


    @PostMapping("/verification")
    @ApiOperation(value = "验证用户token是否有效", notes = "用户访问接口返回是否拥有权限,无需参数")
    public Result<Boolean> verificationToken() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Users user = usersService.findUserByTel(auth.getName());
        return Result.success(user != null);
    }


    @PostMapping("/currentUser")
    @ApiOperation(value = "查询当前用户权限", notes = "根据当前登陆用户token返回用户所有权限,无需参数", produces = "application/json")
    public Result<CurrentUserVO> currentUser() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Users user = usersService.findUserByTel(auth.getName());
        CurrentUserVO userVO = usersService.currentUser(user != null ? user.getTel() : null);
        if (userVO == null) {
            return Result.error(ResponseEnum.NO_TOKEN);
        }

        return Result.success(userVO);
    }


    /**
     * 注册用户
     *
     * @param param
     * @return
     */
    @PostMapping("/register")
    @ApiOperation(value = "注册用户", notes = "通过手机号注册", produces = "application/json")
    public Result<Integer> register(@Valid @RequestBody RegisterUserParam param, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("用户注册失败,{}", Objects.requireNonNull(bindingResult.getFieldError()).getField()
                    + bindingResult.getFieldError().getDefaultMessage());
            return Result.error(ResponseEnum.PARAM_ERROR);
        }
        return usersService.registerUser(param);
    }


    /**
     * 根据用户token查询用户详情信息
     *
     * @param
     * @return
     */
    @GetMapping("/query/userInfo")
    @ApiOperation(value = "根据用户token查询用户详情信息", notes = "通过手机号注册", produces = "application/json")
    @PreAuthorize("hasAnyAuthority('chakanyonghu')")
    public Result<UserBaseInfo> findUserInfo(@ApiIgnore @CurrentUser Users user) {
        return Result.success(usersService.findUserInfoByUserId(user.getUserid()));
    }


    /**
     * 编辑用户详情(t_user_base_info)
     *
     * @param param
     * @return
     */
    @PostMapping("/edit/userInfo")
    @PreAuthorize("hasAnyAuthority('yonghuguanliquan')")
    public Result<Integer> editUserInfo(@RequestBody EditUserInfoParam param, @CurrentUser Users user) {
        param.setUserid(user.getUserid());
        Integer editNum = usersService.editUserInfo(param);
        if (editNum == 0) {
            return Result.error(FailResultEnum.PARAM_ERROR);//返回失败枚举
        }
        //return Result.success(SuccessResultEnum.SUCCESS,editNum);//返回自定义枚举类型
        return Result.success(editNum); //返回默认成功枚举类
    }

    /**
     * 忘记密码
     *
     * @param param
     * @return
     */
    @PostMapping("/forgot/password")
    @ApiOperation(value = "忘记密码", notes = "根据手机号修改密码", produces = "application/json")
    public Result<Integer> forgotPassword(@RequestBody RegisterUserParam param) {
        return usersService.forgotPassword(param);
    }


    /**
     * 用户发送短信
     *
     * @param param
     * @return
     */
    @PostMapping("/sendSmsCode")
    @ApiOperation(value = "用户发送短信验证码")
    public Result<MsgCodeVO> sendSmsCode(@Valid @RequestBody MsgCodeParam param, @ApiIgnore BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("发送短信失败,{}", Objects.requireNonNull(bindingResult.getFieldError()).getField()
                    + bindingResult.getFieldError().getDefaultMessage());
            return Result.error(ResponseEnum.PARAM_ERROR);
        }
        return usersService.sendSmsCode(param);

    }

    /**
     * 根据手机号查询是否已注册过
     * @param param
     * @return
     */
    @PostMapping("/register/query")
    public Result<UserRegisterVO> findUserRegister(@RequestBody UserRegisterParam param) {
        return usersService.findUserRegisterByParam(param);
    }



    /**
     * 用户管理--用户查询接口
     * @param param
     * @return
     */
    @RequestMapping("/queryUser")
    @PreAuthorize("hasAnyAuthority('chakanyonghu')")
    public Result queryUser(@RequestBody UsersParam param){
        return usersService.queryUser(param);
    }

    /**
     * 用户管理--用户禁言/禁用接口
     * @param param
     * @return
     */
    @RequestMapping("/updateUserStatus")
    @PreAuthorize("hasAnyAuthority('yonghuguanliquan')")
    public Result updateUserStatus(@RequestBody UsersParam param){
        return usersService.updateUserStatus(param);
    }

    @RequestMapping("/queryUserDetail")
    @PreAuthorize("hasAnyAuthority('chakanyonghu')")
    public Result<UserVO> queryUserDetail(@RequestBody UsersParam param){
        return usersService.queryUserDetail(param);
    }

    @RequestMapping("/updateTel")
    @PreAuthorize("hasAnyAuthority('yonghuguanliquan')")
    public Result updateTel(@RequestBody UsersUpdateParam param){
        Result result = null;
        try{
            result = usersService.updateTel(param);
        }catch(Exception e){
            result = Result.custom(400, "该用户已注册不可修改", "");
        }
        return result;
    }

    /**
     * 更新用户密码
     * @param param
     * @return
     */
    @RequestMapping("/updatePassword")
    @PreAuthorize("hasAnyAuthority('yonghuguanliquan')")
    public Result updatePassword(@RequestBody UsersUpdateParam param){
        return usersService.updatePassword(param);
    }


    /**
     * 根据token获取用户信息
     * @param user
     * @return
     */
    @GetMapping("/userInfo")
    public Result<UserInfo> queryUserDetail(@CurrentUser Users user){
        return usersService.getUserInfoByUserId(user.getUserid());
    }


    /**
     * 用户退出登录
     * @param
     * @return
     */
    @PostMapping("/signOut")
    public Result<UserInfo> userSignOut() {
        return Result.success(ResponseEnum.SUCCESS);//返回失败枚举
    }

}
